feat(goal): make Goal the sole long-task runtime / Goal 成为唯一长任务状态机 - #7959
Merged
Conversation
Problem: AutoResearch still had active write paths, protocol injection, and desktop surfaces after Goal already owned long-task lifecycle, which left dual completion gates and upgrade ambiguity. Root cause: The previous host-managed AutoResearch runtime remained wired into store writes, Compose, turn orchestration, evaluator evidence, and Wails/TS APIs instead of being reduced to read-only archive recovery. Fix: - Keep Goal as the only state machine for budgets, pause/resume, receipts, update_goal, Delivery readiness, and completion. - Shrink internal/autoresearch to a fail-closed read-only archive reader. - Restore explicit legacy task paths and old sidecars as ordinary research Goals without mutating archive contents or persisting autoResearchTaskID. - Remove AutoResearch runtime/evidence protocol and desktop API surfaces. - Treat Finding.kind as an opaque string; stop enum rejection on write. - Centralize simple/write/research budget selection in taskintent. - Update docs/site and cache-impact coverage for Goal prompt construction. Verification: - go test ./internal/control ./internal/autoresearch ./internal/taskintent ./internal/goaleval ./internal/agent - go test -race ./internal/control ./internal/agent - cd desktop && go test ./... - cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm build - go run ./tools/repolint - scripts/cache-guard.sh - scripts/check-cache-impact.sh Cache-impact: low - ordinary Goal prefixes stay stable; research Goals only drop the old AutoResearch protocol block; provider-visible tool schema and default tool order remain byte-stable.
Problem: models could repeatedly call Goal, planning-only, or background-job tools outside the workflow phase that owns them, leaving no visible answer or operating inherited state.\n\nRoot cause: provider schemas were static and the run-loop repair path recognized only update_goal.\n\nFix: add contextual provider visibility, phase-safe Planner filtering, Goal and Jobs context shadowing, and one bounded generic recovery nudge with focused regression coverage.\n\nVerification: go test ./...; go test -race ./internal/agent ./internal/jobs ./internal/tool ./internal/tool/builtin ./internal/control; go vet ./...; scripts/cache-guard.sh.
Problem: the contextual-tool fix intentionally grows several already-baselined owner and test files, so repo standards rejects the PR.\n\nRoot cause: repolint budgets remained at the pre-fix line and function counts.\n\nFix: raise only the nine affected file/function budgets and add the new complete_step test-file allowance, without rewriting unrelated baseline entries.\n\nVerification: go run ./tools/repolint; git diff --check.
Problem: the latest main-v2 governor merge adds three baselined function and file lines after the Goal PR sync.\n\nRoot cause: the governor commit did not update repository standards budgets before becoming the PR base.\n\nFix: record only the exact e2ebench and agent.go growth reported by repolint.\n\nVerification: go run ./tools/repolint; git diff --check.
Problem: Workflow-only tools could remain model-visible outside their executable context, mixed batches did not repair every unavailable call, and legacy AutoResearch recovery could lose retry state or reactivate after downgrade. Root cause: Tool schemas and child metadata were assembled from static registries, parent runtime services leaked through inherited contexts, and legacy task IDs were cleared before migration persistence was known to succeed. Fix: Filter schemas through ContextualTool, bound mixed-batch repair, isolate child Goal/Jobs/memory state, compute contextual metadata, and make legacy sidecar migration retryable, fail-closed, and downgrade-safe with budgetClass as the authority. Verification: go test ./... -count=1 go test -race ./internal/control ./internal/agent ./internal/jobs ./internal/tool ./internal/tool/builtin ./internal/memory ./internal/autoresearch -count=1 go vet ./... golangci-lint run --timeout=5m cd desktop && go test ./... -count=1 pnpm typecheck; pnpm test:all; pnpm build scripts/cache-guard.sh go run ./tools/repolint git diff --check
Problem: the Goal-only runtime still had provider-context schema filtering assumptions, and an explicit legacy archive could lose its recovery token after a Controller restart.\n\nRoot cause: execution isolation was coupled to provider-visible tool removal, while explicit archive identity lived only in memory and was not distinguished from a sidecar Goal text.\n\nFix: keep stable Registry schemas and enforce Goal, Jobs, and memory boundaries at execution time; add epoch-fenced read-only archive recovery with explicit-path restart handling; preserve unknown Finding kinds and add focused regression coverage.\n\nVerification: go test ./...; go test -race ./internal/control ./internal/agent; cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm build; scripts/cache-guard.sh; scripts/check-cache-impact.sh; go run ./tools/repolint; git diff --check.
Problem: The explicit legacy archive fail-closed test passed on Unix but failed on Windows because chmod zero does not make a file unreadable there. Root cause: The fixture relied on Unix permission semantics instead of creating a platform-independent archive read failure. Fix: Replace task_spec.json with a directory so archive decoding fails deterministically on every supported platform. Verification: go test ./internal/control -count=1 GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go test -c ./internal/control
Problem The PR branch received a concurrent sibling fix while the local branch also integrated the latest main-v2 and completed the Goal-only runtime hardening. Root cause The sibling implementation reintroduced context-dependent provider tool schemas and a pending legacy task field, conflicting with the PR's cache-stability and Goal-state ownership requirements. Fix Merge the remote branch without force-push, retain static provider schemas with execution-time isolation, keep epoch-fenced legacy restoration outside the active Goal machine, and document the reconciled behavior. Verification - go test ./... -count=1 - go test -race ./internal/control ./internal/agent -count=1 - cd desktop && go test ./... -count=1 - desktop/frontend pnpm typecheck, test:all, build - scripts/cache-guard.sh - scripts/check-cache-impact.sh - go run ./tools/repolint - git diff --check
…e-runtime' into feature/goal-sole-runtime
Problem: A concurrent branch reconciliation kept static provider schemas and moved legacy recovery state outside the Goal machine, diverging from the approved esengine#7959 behavior after the latest-base merge. Root cause: The merge resolved overlapping Goal, Jobs, child-context, and tool-registry owner files in favor of an alternative execution-only isolation design. Fix: Restore ContextualTool provider visibility, bounded mixed-call repair, transactional retryable legacy migration, downgrade fencing, contextual metadata, and child Goal/Jobs/memory isolation on top of the merged base. Keep the portable Windows archive-read fixture. Verification: go test ./... -count=1 go test -race ./internal/control ./internal/agent ./internal/jobs ./internal/tool ./internal/tool/builtin ./internal/memory ./internal/autoresearch -count=1 go vet ./... golangci-lint run --timeout=5m cd desktop && go test ./... -count=1 scripts/cache-guard.sh scripts/check-cache-impact.sh go run ./tools/repolint git diff --check
Problem: The PR head had fallen behind main-v2 and GitHub reported a merge conflict after the Skills settings consistency work landed. Root cause: Both branches updated the repository lint baseline while the latest base also changed desktop settings, config loading, and runtime rebuild paths. Fix: Merge main-v2 without rewriting history and regenerate the repolint baseline from the semantically combined tree. Verification: - go test ./... -count=1 - go test -race ./internal/control ./internal/agent -count=1 - go vet ./... - golangci-lint run --timeout=5m - cd desktop && go test ./... -count=1 - cd desktop/frontend && pnpm test:all - cd desktop/frontend && pnpm build - scripts/cache-guard.sh - scripts/check-cache-impact.sh - go run ./tools/repolint - git diff --check
Problem Legacy archive retry identity lived inside the active Goal machine, and the removed AutoResearch readiness reader still carried a second completion contract. Root cause Archive failures depended on a Goal-owned task token that was written back into new sidecars and could be mistaken for an active AutoResearch runtime. Fix Keep archive identity only in the Controller-owned read-only recovery boundary, fence ordinary Goal resume for legacy failures, omit deprecated sidecar fields, and fold finding compatibility checks into the read-only summary path. Verification Focused legacy restore, finding compatibility, control, agent, boot, and autoresearch tests pass; git diff --check passes.
…runtime-fix # Conflicts: # desktop/frontend/src/__tests__/stream-delta-batch.test.ts # tools/repolint/baseline.json
Problem: The Goal/runtime fixes added lines and complexity to several files already at their repolint debt ceilings, causing the repository gate to fail after merging the latest baseline. Root cause: Contextual tool visibility, legacy durability helpers, and their tests were implemented inline in large owner files instead of dedicated modules. Fix: Extract workflow context, planner registry, subagent identity, Goal durability, Jobs context, CLI Goal handling, and focused tests into scoped files. Keep provider behavior unchanged and add the new schema-bearing files to cache-impact coverage. Verification: go test ./internal/agent ./internal/boot ./internal/control ./internal/jobs ./internal/tool/builtin -count=1; go run ./tools/repolint; git diff --check
Problem: The PR made provider-visible schemas conditional on Goal, Plan, and Jobs context, removing update_goal from ordinary and economy requests and violating the required byte-stable tool contract. Root cause: A broad contextual-tool mechanism was added while hardening Goal recorder isolation, coupling an execution boundary to provider schema selection. Fix: Restore static Schemas() requests and the main-v2 tool order, remove contextual schema APIs and phase-specific visibility, and keep only execution-time Goal recorder isolation for planners and child agents. Correct the changelog and cache-impact coverage. Verification: go test ./internal/agent ./internal/boot ./internal/control ./internal/tool ./internal/tool/builtin -count=1; go run ./tools/repolint; git diff --exit-code origin/main-v2 -- internal/agent/extensions.go internal/agent/run_loop.go internal/agent/sampling_request.go internal/tool/tool.go internal/tool/builtin/bgjobs.go internal/tool/builtin/completestep.go internal/tool/builtin/updategoal.go internal/jobs/jobs.go internal/memory/queue.go; git diff --check
Problem The Goal-only migration still exposed a stale Desktop AutoResearch mock, retained a removed variadic setup shape, and reopened a legacy archive after it had already been validated. Root cause Compatibility cleanup stopped short of the final source-level boundary, and the archive goal loader performed redundant validation after LoadTask had bound and verified the archive snapshot. Fix Remove the stale Desktop mock and variadic argument, document the evidence sanitizer as display-only, and use the single validated LoadTask result for legacy goal recovery. Verification - go test ./internal/control ./internal/autoresearch ./internal/agent ./internal/taskintent ./internal/boot ./internal/tool -count=1 - go test -race ./internal/control ./internal/agent ./internal/jobs ./internal/tool ./internal/tool/builtin ./internal/memory ./internal/autoresearch -count=1 - go test ./... -count=1 - cd desktop && go test ./... -count=1 - cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm build - go vet ./... - golangci-lint run --timeout=5m - scripts/cache-guard.sh - go run ./tools/repolint - git diff --check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make Goal the only long-running task state machine. AutoResearch is reduced to a fail-closed, read-only compatibility reader for historical
.reasonix/autoresearch/<task-id>/archives. New runs no longer create archives, inject AutoResearch protocol, write findings, or expose AutoResearch through CLI help, Desktop APIs, or frontend state.The default provider-visible tool schemas and order remain byte-stable with
main-v2. Planner and child-agent isolation is enforced through host-side Goal recorders, not dynamic schema visibility.Changes
internal/taskintent: simple 10 turns, write 20 turns, and research 40 turns.update_goal, bounded evaluation, and completion/blocking gates.internal/autoresearchto a read-only archive reader with task-ID validation, workspace confinement, symlink and traversal rejection, JSON schema validation, bounded JSONL records, and file-identity checks..reasonix/autoresearch/<task-id>/inputs using the archived original objective, then run an ordinary research-budget Goal.autoResearchTaskIDsidecars, preserve Goal state, todos, Delivery checkpoints, and consumed budget, and fill missing objective text fromtask_spec.jsonwhen required.autoResearchTaskID; current writes setresearchMode=Offas a downgrade fence.Finding.kindas an opaque string soverificationand unknown future values remain readable and displayable.<autoresearch-evidence>transcript blocks; current Goal semantics do not parse those blocks or write state from them.Compatibility
autoResearchTaskIDbudgetClassresearchModeOffFinding.kindverification, unknown values, and empty legacy valuesmain-v2; planner/child contexts only replace the Goal recorderNo replacement AutoResearch API is introduced.
GoalRuntimeis the only current long-task runtime surface.Security and concurrency
LoadTaskresult, avoiding a second reopen that could observe a different filesystem generation.Cache impact
Cache-impact: low.
<autoresearch-runtime>block.main-v2.Cache-guard:
scripts/cache-guard.shcovers ordinary dialogue, long dialogue, tool loops, and boot extension composition; Goal prompt construction paths are included inscripts/check-cache-impact.sh.System-prompt-review: completed. The expected prompt change is limited to removing the AutoResearch runtime protocol from research Goals.
Documentation impact
Documentation-impact: updated - English and Chinese Guide/SPEC/Goal Enforcement/collaboration/site documentation now describe Goal-only automatic budgets and read-only legacy archive compatibility. Historical AutoResearch design and audit documents are marked superseded.
Verification
go test ./... -count=1go test -race ./internal/control ./internal/agent ./internal/jobs ./internal/tool ./internal/tool/builtin ./internal/memory ./internal/autoresearch -count=1go vet ./...golangci-lint run --timeout=5mcd desktop && go test ./... -count=1cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm buildgo run ./tools/repolintscripts/cache-guard.shscripts/check-cache-impact.shgit diff --checkFocused regression coverage includes budget classification, Goal continuation/pause/resume/completion, old-sidecar and explicit-path recovery, fail-closed archive errors, archive immutability, opaque finding kinds, protocol removal, static provider tool contracts, and removal of Desktop AutoResearch surfaces.
Integration notes
main-v2; the resulting merge tree is clean locally.